#pragma once

#include "event.h"


namespace evm { namespace event {

using namespace std;

using TimerHandler = function<void ()>;

struct PeriodTimer {
    /* Constructed a disabled timer. */
    PeriodTimer(EventLoop* loop) : PeriodTimer(0, 0, nullptr, loop) {}

    /* Constructed a timer, with initial expiration time, periodic expiration time, and timer handler. */
    PeriodTimer(double initial, double period, TimerHandler handler, EventLoop* loop);

    ~PeriodTimer();

    /* Set and start the timer, with initial expiration time, periodic expiration time,
     * and optional timer handler (if not null, override the original one). */
    void set(double initial, double period, TimerHandler handler = nullptr);

    /* Stop the timer. */
    void stop();

protected:
    TimerHandler handler_;
    EventLoop* loop_;
    int fd_;
};

using PeriodTimerPtr = shared_ptr<PeriodTimer>;

struct OneshotTimer : PeriodTimer {
    OneshotTimer(EventLoop* loop) : OneshotTimer(0, nullptr, loop) {}

    OneshotTimer(double initial, TimerHandler handler, EventLoop* loop);

    void set(double initial, TimerHandler handler = nullptr);
};

using OneshotTimerPtr = shared_ptr<OneshotTimer>;

}}
